﻿using Kingdee.BOS.App.Data;
using Kingdee.BOS.Core.CommonFilter;
using Kingdee.BOS.Core.DependencyRules;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.DynamicForm.PlugIn.ControlModel;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.Core.Report;
using Kingdee.BOS.JSON;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;

namespace WSDZ.KM.ZH.OutsourceExpenseBlitemReconciliation
{
    [Description("委外耗用盘点单委外对账"), HotUpdate]
    public class OutsourceReconciliation : AbstractDynamicFormPlugIn
    {
        public string btype = "委外耗用盘点单委外对账";
        public string entyKey = "FEntity";
        public string currentFormId = string.Empty;
        public override void AfterBindData(EventArgs e)
        {
            base.AfterBindData(e);
            currentFormId = View.BillBusinessInfo.GetForm().Id;
        }
        public override void ButtonClick(ButtonClickEventArgs e)
        {
            base.ButtonClick(e);
            //委外对账
            if (e.Key.EqualsV1("F_RLKX_Buttondz"))
            {
                try
                {
                    Reconciliation();
                }
                catch (Exception ex)
                {
                    View.ShowErrMessage(ex.Message);
                }
            }
        }
        /// <summary>
        /// 委外对账
        /// </summary>
        public void Reconciliation()
        {
            List<PickData> pickList = new List<PickData>();
            List<BalanceOfBegin> balanceList = new List<BalanceOfBegin>();
            List<BalanceOfBegin> purPriceList = new List<BalanceOfBegin>();
            List<InventoryData> inventoryList = new List<InventoryData>();
            string d1 = Model.GetValue("F_RLKX_SDate").ToStringV1();
            string d2 = Model.GetValue("F_RLKX_EDate").ToStringV1();
            int orgId = 0;
            int stockId = 0;
            int stockMastId = 0;
            int suppId = 0;
            if (d1.IsNullOrEmptyOrWhiteSpace() || d2.IsNullOrEmptyOrWhiteSpace())
            {
                View.ShowErrMessage("开始、结束日期不可空!!!");
                return;
            }
            DynamicObject orgObj = Model.GetValue("F_RLKX_OrgId") as DynamicObject;
            if (orgObj != null)
                orgId = orgObj["Id"].ToStringV1().ToInt32V1();
            if (orgId == 0)
            {
                View.ShowErrMessage("组织不可为空!!!");
                return;
            }
            DynamicObject stockObj = Model.GetValue("F_RLKX_jgsck") as DynamicObject;
            if (stockObj != null)
            {
                stockId = stockObj["Id"].ToStringV1().ToInt32V1();
                stockMastId= stockObj["msterID"].ToStringV1().ToInt32V1();
            }
            if (stockId == 0)
            {
                View.ShowErrMessage("仓库不可为空!!!");
                return;
            }
            DynamicObject suppObj = Model.GetValue("F_RLKX_gys") as DynamicObject;
            if (suppObj != null)
                suppId = suppObj["Id"].ToStringV1().ToInt32V1();
            if (suppId == 0)
            {
                View.ShowErrMessage("供应商不可为空!!!");
                return;
            }
            Model.DeleteEntryData(entyKey);

            string date1 = d1.ToDateTime().ToString("yyyy-MM-dd");
            string date2 = d2.ToDateTime().ToString("yyyy-MM-dd 23:59:59");

            //获取领料数据
            {
                string sql = $@"/*dialect*/ select 
matId=pickInfo.matId
,mastId=pickInfo.mastId
,matNumber=pickInfo.matNumber
,unitId=pickInfo.unitId
,wasteRate=pickInfo.wasteRate
,wasteQty=(ISNULL(pickInfo.pickQty,0)-ISNULL(returnInfo.tlQty,0))*pickInfo.wasteRate  --合理损耗数量
,wwllQty=ISNULL(pickInfo.pickQty,0)-ISNULL(returnInfo.tlQty,0) --委外领料数量
from (
select 
matId=mat.FMATERIALID
,mastId=mat.FMASTERID
,matNumber=mat.FNUMBER
,unitId=pickEnty.FUNITID
,wasteRate=ISNULL(mat.F_RLKX_SHRATE,0) --委外损耗率
,num=ROW_NUMBER() over(partition by mat.FMATERIALID order by mat.FMATERIALID)
,pickQty=SUM(ISNULL(pickEnty.FACTUALQTY,0)) over(partition by mat.FMATERIALID)
from T_SUB_PICKMTRL pick
left join T_SUB_PICKMTRLDATA pickEnty on pick.FID=pickEnty.FID
left join T_BD_MATERIAL mat on pickEnty.FMATERIALID=mat.FMATERIALID
--left join T_BD_UNIT unit on pickEnty.FUNITID=unit.FUNITID
where pick.FDOCUMENTSTATUS='C'
and pick.FSTOCKORGID={orgId}
and pick.FSUPPLIERID={suppId}
and pickEnty.FSTOCKID={stockId}
and pick.FDATE>='{date1}'
and pick.FDATE<='{date2}'
) pickInfo
left join
(
select 
matId=mat.FMATERIALID
,matNumber=mat.FNUMBER
,num=ROW_NUMBER() over(partition by mat.FMATERIALID order by mat.FMATERIALID)
,tlQty=SUM(ISNULL(tlEnty.FQTY,0)) over(partition by mat.FMATERIALID)
from T_SUB_RETURNMTRL tl
left join T_SUB_RETURNMTRLENTRY tlEnty on tl.FID=tlEnty.FID
left join T_BD_MATERIAL mat on tlEnty.FMATERIALID=mat.FMATERIALID
where tl.FDOCUMENTSTATUS='C'
and tl.FSTOCKORGID={orgId}
and tl.FSUBSUPPLIERID={suppId}
and tlEnty.FSTOCKID={stockId}
and tl.FDATE>='{date1}'
and tl.FDATE<='{date2}'
)returnInfo on pickInfo.matId=returnInfo.matId and pickInfo.num=returnInfo.num
where pickInfo.num=1";
                DynamicObjectCollection datas = DBUtils.ExecuteDynamicObject(Context,sql);
                if (datas==null&&datas.Count<1)
                    return;
                pickList = datas.DynamicObjectCollectionToDataList<PickData>();
            }
            //获取期初结存单价
            {
                string sql = $@"/*dialect*/ select * from (
select 
matId=mat.FMATERIALID
,cbprice=(case when sum(FQTY) !=0 then sum(FAMOUNT)/sum(FQTY) else 0 end)
from V_HS_OUTACCTG a
join V_HS_Balance b on a.FID=b.FID
left join T_BD_MATERIAL mat on b.FMASTERID=mat.FMASTERID and mat.FUSEORGID=a.facctgorgid
join
(
select FORGID,max(FCLOSEDATE) FCLOSEDATE from t_stk_closeprofile where fcategory='HS' group by 
FORGID 
) c on a.facctgorgid=c.FORGID and convert(varchar(7),a.FDATE,121)=convert(varchar(7),DATEADD(month,-1,c.FCLOSEDATE),121)
where a.facctgorgid={orgId} and ISNULL(mat.FMATERIALID,0)<>0
group by mat.FMATERIALID
)A where cbprice>0";
                DynamicObjectCollection datas = DBUtils.ExecuteDynamicObject(Context, sql);
                if (datas != null && datas.Count > 0)
                {
                    balanceList = datas.DynamicObjectCollectionToDataList<BalanceOfBegin>();
                }
            }
            //获取采购价目表单价
            {
                string sql = $@"/*dialect*/ select 
matId
,price
from (
select 
matId=mat.FMATERIALID
,price=enty.FPRICE
,num=ROW_NUMBER() over(partition by mat.FNUMBER order by enty.FEFFECTIVEDATE desc)
from t_PUR_PriceListEntry enty
left join t_PUR_PriceList main on enty.FID=main.FID
left join T_BD_MATERIAL mat on enty.FMATERIALID=mat.FMATERIALID
where main.FDOCUMENTSTATUS='C'
and main.FUSEORGID={orgId}
and main.FSupplierId={suppId}
and ISNULL(main.FFORBIDSTATUS,'A')='A'
)A where num=1";
                DynamicObjectCollection datas = DBUtils.ExecuteDynamicObject(Context, sql);
                if (datas != null && datas.Count > 0)
                {
                    purPriceList = datas.DynamicObjectCollectionToDataList<BalanceOfBegin>();
                }
            }
            //查询即时库存
            {
                string sql = $@"/*dialect*/ select 
matId=mat.FMATERIALID
,unitId=jsck.FBASEUNITID
,qty=ISNULL(jsck.FBASEQTY,0)
from T_STK_INVENTORY jsck
left join T_BD_STOCK stock on jsck.FSTOCKID=stock.FSTOCKID
left join T_BD_MATERIAL mat on jsck.FMATERIALID=mat.FMATERIALID
where jsck.FSTOCKORGID={orgId}
and stock.FMASTERID={stockMastId}";
                DynamicObjectCollection datas = DBUtils.ExecuteDynamicObject(Context, sql);
                if (datas != null && datas.Count > 0)
                {
                    inventoryList = datas.DynamicObjectCollectionToDataList<InventoryData>();
                    inventoryList = inventoryList.GroupBy(x => x.matId).Select(x =>
                    {
                        InventoryData fobj = x.FirstOrDefault();
                        fobj.qty = x.Sum(a => a.qty);
                        return fobj;
                    }).ToList();
                }
            }

            List<int> matIdList = new List<int>();
            List<int> matIds1 = pickList.Select(x => x.matId).ToList();
            List<int> matIds2 = inventoryList.Select(x => x.matId).ToList();
            if (matIds1!=null)
                matIdList.AddRange(matIds1);
            if (matIds2 != null)
                matIdList.AddRange(matIds2);
            matIdList = matIdList.Distinct().ToList();

            List<PickData> dataList = new List<PickData>();
            foreach (int matId in matIdList)
            {
                PickData data = new PickData();
                PickData pickObj = pickList.Where(x => x.matId == matId).FirstOrDefault();
                if (pickObj!=null)
                {
                    data.matId = pickObj.matId;
                    data.unitId = pickObj.unitId;
                    data.wasteQty = pickObj.wasteQty;
                    data.wwllQty = pickObj.wwllQty;
                }
                var inventoryObj = inventoryList.Where(a => a.matId == matId).FirstOrDefault();
                if (inventoryObj != null)
                {
                    data.inventoryQty = inventoryObj.qty;
                    if (data.matId==0)
                    {
                        if (inventoryObj.qty==0)
                        {
                            continue;
                        }
                        else
                        {
                            data.matId = inventoryObj.matId;
                            data.unitId = inventoryObj.unitId;
                        }
                    }
                }
                var balanceObj = balanceList.Where(a => a.matId == matId).FirstOrDefault();
                if (balanceObj != null)
                    data.inventoryPrice = balanceObj.cbprice;
                else
                {
                    var priceObj = purPriceList.Where(a => a.matId == matId).FirstOrDefault();
                    if (priceObj != null)
                        data.inventoryPrice = priceObj.price;
                }
                dataList.Add(data);
            }

            //pickList = pickList.Select(x =>
            //{
            //    var inventoryObj = inventoryList.Where(a => a.matId == x.matId).FirstOrDefault();
            //    if (inventoryObj!=null)
            //        x.inventoryQty = inventoryObj.qty;
            //    var balanceObj = balanceList.Where(a => a.mastId == x.mastId).FirstOrDefault();
            //    if (balanceObj != null)
            //        x.inventoryPrice = balanceObj.cbprice;
            //    else
            //    {
            //        var priceObj = purPriceList.Where(a => a.matId == x.matId).FirstOrDefault();
            //        if (priceObj != null)
            //            x.inventoryPrice = priceObj.price;
            //    }
            //    return x;
            //}).ToList();

            FillEntry(dataList);
        }
        public void FillEntry(List<PickData> pickList)
        {
            if (pickList == null || pickList.Count < 1)
                return;
            int seq = 0;
            foreach (var data in pickList)
            {
                Model.CreateNewEntryRow(entyKey);
                Model.SetItemValueByID("F_RLKX_materialid", data.matId, seq);
                Model.SetItemValueByID("F_RLKX_UnitID", data.unitId, seq);
                Model.SetValue("F_RLKX_Qtyhxsh", data.wasteQty,seq);
                Model.SetValue("F_RLKX_Qtyjs", data.inventoryQty, seq);
                Model.SetValue("F_RLKX_Price", data.inventoryPrice, seq);
                //委外领料数量
                Model.SetValue("F_RLKX_Qtysl", data.wwllQty, seq);

                Model.SetValue("F_RLKX_scfs", "A", seq);

                Model.SetValue("F_RLKX_Qtyjgcpd", 0);
                Model.SetValue("F_RLKX_BillStatuskctz","A");
                seq++;
            }
            View.UpdateView(entyKey);
        }

        //public void FillEntry(List<PickData> pickList)
        //{
        //    if (pickList == null || pickList.Count < 1)
        //        return;
        //    Entity entity = this.Model.BillBusinessInfo.GetEntity(entyKey);
        //    DynamicObjectCollection rows = this.Model.GetEntityDataObject(entity);
        //    int seq = 1;
        //    foreach (var data in pickList)
        //    {
        //        DynamicObject row = new DynamicObject(entity.DynamicObjectType);
        //        entity.SeqDynamicProperty.SetValue(row, seq);
        //        DynamicObject matObj = UtilityManager.GetDynamicObjectById(Context, currentFormId, "F_RLKX_materialid", data.matId);
        //        if (matObj != null)
        //        {
        //            row["F_RLKX_materialid_Id"] = data.matId;
        //            row["F_RLKX_materialid"] = matObj;
        //            //View.InvokeFieldUpdateService("F_RLKX_custno", seq);
        //        }
        //        DynamicObject unitObj = UtilityManager.GetDynamicObjectById(Context, currentFormId, "F_RLKX_UnitID", data.unitId);
        //        if (unitObj != null)
        //        {
        //            row["F_RLKX_UnitID_Id"] = data.unitId;
        //            row["F_RLKX_UnitID"] = unitObj;
        //        }
        //        row["F_RLKX_Qtyhxsh"] = data.wasteQty;
        //        row["F_RLKX_Qtyjs"] = data.inventoryQty;
        //        row["F_RLKX_Price"] = data.inventoryPrice;
        //        row["F_RLKX_Qtyjgcpd"] = 0;
        //        rows.Add(row);
        //        seq++;
        //    }
        //    this.View.UpdateView();
        //    //View.UpdateView(entyKey);
        //    //for (int i = 0; i < seq; i++)
        //    //{
        //    //    //View.InvokeFieldUpdateService("F_RLKX_Qtyjs", i+1);
        //    //    //View.InvokeFieldUpdateService("F_RLKX_Qtyjgcpd", i+1);
        //    //}
        //}

    }
    public class PickData
    {
        public int matId { get; set; }
        public int mastId { get; set; }
        public string matNumber { get; set; }
        public int unitId { get; set; }
        public string unitNumber { get; set; }
        public decimal wasteRate { get; set; }
        public decimal wasteQty { get; set; }
        public decimal inventoryPrice { get; set; }
        public decimal inventoryQty { get; set; }
        public decimal wwllQty { get; set; }
    }
    public class BalanceOfBegin
    {
        public int matId { get; set; }
        public int mastId { get; set; }
        public decimal cbprice { get; set; }
        public decimal price { get; set; }
    }
    public class InventoryData
    {
        public int matId { get; set; }
        public int unitId { get; set; }
        public decimal qty { get; set; }
    }
}
